package com.ybw.order.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.ybw.order.demo.constant.MqConstant;
import com.ybw.order.demo.entity.GoodsInfo;
import com.ybw.order.demo.entity.OrderInfo;
import com.ybw.order.demo.exception.BizException;
import com.ybw.order.demo.mapper.GoodsInfoMapper;
import com.ybw.order.demo.mapper.OrderInfoMapper;
import com.ybw.order.demo.service.GoodsInfoService;
import com.ybw.order.demo.service.OrderInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ybw.order.demo.utils.MyStringUtils;
import com.ybw.order.demo.vo.CancelOrderVO;
import com.ybw.order.demo.vo.CreateOrderVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.MessageConst;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author ybwei
 * @since 2022-02-20
 */
@Service
@Slf4j
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
    @Resource
    private GoodsInfoService goodsService;
    @Resource
    private GoodsInfoMapper goodsInfoMapper;
    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrder(CreateOrderVO createOrderVO) {
        //1、获取商品信息
        GoodsInfo goods = goodsService.getById(createOrderVO.getGoodsId());
        log.info("剩余库存：{}", goods.getStockCount());
        //1.1 校验
        if (goods == null || goods.getIsAllowSale() == 0 || goods.getStockCount().intValue() < createOrderVO.getBuyCount().intValue()) {
            log.info("check fail");
            throw new BizException("check fail");
        }
        //2、修改库存
        goodsService.lambdaUpdate()
                .eq(GoodsInfo::getId, goods.getId())
                .set(GoodsInfo::getStockCount, goods.getStockCount() - createOrderVO.getBuyCount()).update();
        //3、创建订单
        OrderInfo order = new OrderInfo();
        order.setOrderNo(createOrderVO.getOrderNo());
        order.setGoodsId(createOrderVO.getGoodsId());
        order.setBuyCount(createOrderVO.getBuyCount());
        order.setSalePrice(goods.getSalePrice());
        order.setPayPrice(createOrderVO.getPayPrice());
        order.setStatus(0);
        save(order);
        //4、mq延迟队列
        asyncDelaySend(createOrderVO.getOrderNo());
        log.info("success");
    }

    /**
     * mq延迟队列
     *
     * @param orderNo
     * @methodName: asyncDelaySend
     * @return: void
     * @author: geoffrey
     * @date: 2022/2/20
     **/
    public void asyncDelaySend(String orderNo) {
        //messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
        //4 指的是30s
        Message<String> message = MessageBuilder.withPayload(orderNo)
                .setHeader(MessageConst.PROPERTY_KEYS, MyStringUtils.generateUUID())
                .setHeader(MessageConst.PROPERTY_PRODUCER_GROUP, MqConstant.PRODUCER_GROUP)
                .build();
        rocketMQTemplate.asyncSend(MqConstant.TOPIC, message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("asyncDelaySend:{}", JSON.toJSONString(sendResult));
            }

            @Override
            public void onException(Throwable e) {
                log.error("消息发送失败,消息体:{}", JSON.toJSONString(message), e);
            }

        }, 2000, 5);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrder(CancelOrderVO cancelOrderVO) {
        OrderInfo orderInfo = this.lambdaQuery()
                .eq(OrderInfo::getOrderNo, cancelOrderVO.getOrderNo())
                .one();
        if (orderInfo == null || orderInfo.getStatus() != 0) {
            //为空 或 状态！=待支付
            log.info("为空 或 状态！=待支付");
            return;
        }
        //2、修改库存
        goodsInfoMapper.updateStockCount(orderInfo.getGoodsId(), orderInfo.getBuyCount());
        GoodsInfo goods = goodsService.getById(orderInfo.getGoodsId());
        if (goods == null) {
            return;
        }
        if (goods.getStockCount() > goods.getTotalStockCount()) {
            throw new BizException("超过总库存量");
        }
        //3、修改订单状态
        this.lambdaUpdate()
                .set(OrderInfo::getStatus, 2)
                .eq(OrderInfo::getId, orderInfo.getId())
                .update();
    }

    @Override
    public void notifyOrder(String orderNo) {
        this.lambdaUpdate()
                .eq(OrderInfo::getOrderNo, orderNo)
                .eq(OrderInfo::getStatus,0)
                .set(OrderInfo::getStatus, 1)
                .update();
    }
}
